package com.symaster.common.swing.element;

import com.symaster.common.swing.style.Style;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Set;

/**
 * @author yinmiao
 * @date 2021-11-22 15:32
 */
public class MyInput extends JComponent {
    private JPanel root_panel;
    private JTextField tips;
    private JTextField input;
    private JPanel line;
    private Set<MyFocusListener> forFocusListeners;
    private Set<ValueChangeListener> valueChangeListeners;
    private Set<EnterKeyListener> enterKeyListeners;
    private String lastValue = "";
    private String tipsText;
    private boolean enabled = true;

    public MyInput() {
        initLayout();
        initPage();
        initListener();
    }

    public MyInput(String tips, boolean isInputArea) {
        initLayout();
        this.tipsText = tips;
        initData(tips, isInputArea);
        initPage();
        initListener();
    }

    public void addEnterKeyListener(EnterKeyListener listener) {
        if (enterKeyListeners == null) {
            enterKeyListeners = new HashSet<>();
        }
        enterKeyListeners.add(listener);
    }

    @Override
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
        input.setEnabled(enabled);
    }

    public void selectAll() {
        input.selectAll();
    }

    /**
     * 添加焦点事件
     */
    public void addFocusListener(MyFocusListener listener) {
        if (forFocusListeners == null) {
            forFocusListeners = new HashSet<>();
        }
        forFocusListeners.add(listener);
    }

    /**
     * 添加值发生改变事件
     */
    public void addValueChangeListener(ValueChangeListener listener) {
        if (valueChangeListeners == null) {
            valueChangeListeners = new HashSet<>();
        }
        valueChangeListeners.add(listener);
    }

    /**
     * 获得焦点事件
     */
    private void myFocusGained() {
        if (!enabled) {
            return;
        }
        line.setBackground(new Color(249, 130, 108));
        if (forFocusListeners != null) {
            for (MyFocusListener forFocusListener : forFocusListeners) {
                forFocusListener.focusGained();
            }
        }
    }

    /**
     * 失去焦点事件
     */
    private void myFocusLost() {
        line.setBackground(new Color(51, 58, 65));
        if (forFocusListeners != null) {
            for (MyFocusListener forFocusListener : forFocusListeners) {
                forFocusListener.focusLost();
            }
        }
    }

    private void valueChangeListener(DocumentEvent e) {
        Document document = e.getDocument();
        String text = null;
        try {
            text = document.getText(0, document.getLength());
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }
        if (valueChangeListeners != null && valueChangeListeners.size() > 0) {
            for (ValueChangeListener valueChangeListener : valueChangeListeners) {
                valueChangeListener.handle(lastValue, text);
            }
        }
        lastValue = text;
    }

    private void initListener() {
        input.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                myFocusGained();
            }

            @Override
            public void focusLost(FocusEvent e) {
                myFocusLost();
            }
        });
        Document document = input.getDocument();
        document.addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                valueChangeListener(e);
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                valueChangeListener(e);
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                valueChangeListener(e);
            }
        });
        input.registerKeyboardAction(e -> {
            if (enterKeyListeners == null || enterKeyListeners.size() <= 0) {
                return;
            }
            for (EnterKeyListener enterKeyListener : enterKeyListeners) {
                enterKeyListener.handle(input.getText());
            }
        }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    }

    public String getTipsText() {
        return tipsText;
    }

    public void setTipsText(String tipsText) {
        this.tipsText = tipsText;
        this.tips.setText(tipsText);
    }

    public String getValue() {
        return input.getText();
    }

    public void setValue(String value) {
        input.setText(value);
    }

    private void initData(String tips, boolean isInputArea) {
        this.tips.setText(tips);
    }

    private void initPage() {
        Style.setBorder(1, tips, input);
        Style.setFont(1, tips, input);
    }

    private void initLayout() {
        this.setLayout(new BorderLayout());
        this.add(root_panel, BorderLayout.CENTER);
    }

    {
        // GUI initializer generated by IntelliJ IDEA GUI Designer
        // >>> IMPORTANT!! <<<
        // DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        root_panel = new JPanel();
        root_panel.setLayout(new BorderLayout(0, 0));
        root_panel.setBackground(new Color(-14801880));
        root_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(new Color(-13683139)), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        tips = new JTextField();
        tips.setBackground(new Color(-14801880));
        tips.setEditable(false);
        tips.setForeground(new Color(-6378057));
        root_panel.add(tips, BorderLayout.WEST);
        input = new JTextField();
        input.setBackground(new Color(-14801880));
        input.setCaretColor(new Color(-425364));
        input.setDisabledTextColor(new Color(-9340027));
        input.setForeground(new Color(-2231553));
        input.setName("");
        input.setToolTipText("");
        root_panel.add(input, BorderLayout.CENTER);
        line = new JPanel();
        line.setLayout(new BorderLayout(0, 0));
        line.setBackground(new Color(-13419967));
        line.setPreferredSize(new Dimension(0, 1));
        root_panel.add(line, BorderLayout.SOUTH);
        line.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
    }

    /** @noinspection ALL */
    public JComponent $$$getRootComponent$$$() {
        return root_panel;
    }

    public interface MyFocusListener extends EventListener {

        void focusGained();

        void focusLost();
    }

    public interface ValueChangeListener extends EventListener {
        void handle(String oldValue, String newValue);
    }

    public interface EnterKeyListener extends EventListener {
        void handle(String value);
    }

}
